//**** Frame FAS search and check module ***//

module OH_PTR(
   RESET,
   RCLK_155M,

   DBIN_FAS_FAIL,
   DBIN_SOH_FAIL,
   DBIN_FCNT8,
   DBIN_FCNT270,
   DBIN_FCNT9,
   DBIN_DATA,

   DBOUT_NOCAT,
   DBOUT_FCNT8,
   DBOUT_FCNT270,
   DBOUT_FCNT9,
   DBOUT_DATA,
   DBOUT_SPE,
   DBOUT_J1
   );

input              RESET;
input              RCLK_155M;

input              DBIN_FAS_FAIL;
input              DBIN_SOH_FAIL;
input[2:0]         DBIN_FCNT8;
input[8:0]         DBIN_FCNT270;
input[3:0]         DBIN_FCNT9;
input[63:0]        DBIN_DATA;

output reg         DBOUT_NOCAT;
output reg[2:0]    DBOUT_FCNT8;
output reg[8:0]    DBOUT_FCNT270;
output reg[3:0]    DBOUT_FCNT9;
output reg[63:0]   DBOUT_DATA;
output reg         DBOUT_SPE;
output reg         DBOUT_J1;

// signals for point format/event check
reg                PTCHK_YYPOS, PTCHK_FFPOS;
reg                PTCHK_H1POS, PTCHK_H2POS;
reg[7:0]           PTCHK_CURRENT_H1, PTCHK_CURRENT_H2;                       // captured H1,H2 bytes from data stream
reg[7:0]           PTCHK_PREVIOUS_H1, PTCHK_PREVIOUS_H2;     // registerdd H1,H2 of previous frame
reg                PTCHK_EVT_RENEW;                 // event status renew position flag, asserted the last postion of H2
reg[9:0]           PTCHK_EVT_PNT;
reg                PTCHK_EVT_IBIT, PTCHK_EVT_DBIT;     //
reg                PTCHK_EVT_ILLEGAL;
reg                PTCHK_EVT_STABLE;
reg                PTCHK_EVT_NDF;
reg                PTCHK_EVT_AIS;
reg                PTCHK_EVT_CONTINUE;

reg                PTFSM_RENEW;
reg[2:0]           PTFSM_FSM;
parameter          C_FSM_LOP    = 3'b000;
parameter          C_FSM_AIS    = 3'b001;
parameter          C_FSM_NORMAL = 3'b010;
parameter          C_FSM_INC    = 3'b011;
parameter          C_FSM_DEC    = 3'b100;
reg[1:0]           PTFSM_CNT_AIS;
reg[3:0]           PTFSM_CNT_NDF;
reg[3:0]           PTFSM_CNT_UNSTABLE;
reg[1:0]           PTFSM_CNT_STABLE;
reg[9:0]           PTFSM_PNT;
reg[2:0]           PTFSM_FCNT8;
reg[8:0]           PTFSM_FCNT270;
reg[3:0]           PTFSM_FCNT9;
reg[63:0]          PTFSM_DATA;

reg                J1SPE_DATAEN;
wire               J1SPE_BASE_EN;
reg[11:0]          J1SPE_J1CNT;    // [1:0]   counter 0-2       [11:2]      counter 0-782


//******                   input pointer check                    ******//
// check the Y* and 1* to confirm the concatenation pointer
always @( DBIN_FCNT8 or DBIN_FCNT270 or DBIN_FCNT9) begin
   if ( DBIN_FCNT9[3:0]==4'd3 ) begin
      if ( DBIN_FCNT270[8:0]==9'd0 && DBIN_FCNT8[2:0]!=3'd0 )
         PTCHK_YYPOS              <= 1'b1;
      else if ( DBIN_FCNT270[8:0]==9'd1 && DBIN_FCNT270[8:0]==9'd2 )
         PTCHK_YYPOS              <= 1'b1;
      else
         PTCHK_YYPOS              <= 1'b0;
   end
   else begin
         PTCHK_YYPOS              <= 1'b0;
   end
end
always @( DBIN_FCNT8 or DBIN_FCNT270 or DBIN_FCNT9) begin
   if ( DBIN_FCNT9[3:0]==4'd3 ) begin
      if ( DBIN_FCNT270[8:0]==9'd3 && DBIN_FCNT8[2:0]!=3'd0 )
         PTCHK_FFPOS              <= 1'b1;
      else if ( DBIN_FCNT270[8:0]==9'd4 && DBIN_FCNT270[8:0]==9'd5 )
         PTCHK_FFPOS              <= 1'b1;
      else
         PTCHK_FFPOS              <= 1'b0;
   end
   else begin
         PTCHK_FFPOS              <= 1'b0;
   end
end

always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      DBOUT_NOCAT                 <= 1'b0;
   else begin
      if ( PTCHK_YYPOS==1'b1 && DBIN_DATA[63:0]!=64'h9b9b9b9b_9b9b9b9b )
         DBOUT_NOCAT              <= 1'b1;
      else if ( PTCHK_FFPOS==1'b1 && DBIN_DATA[63:0]!=64'hffffffff_ffffffff )
         DBOUT_NOCAT              <= 1'b1;
      else
         DBOUT_NOCAT              <= 1'b0;
   end
end

// capture H1/H2 at and generate H1/H2 
always @( DBIN_FCNT9 or DBIN_FCNT270 or DBIN_FCNT8 ) begin
   if ( DBIN_FCNT9[3:0]==4'd3 && DBIN_FCNT270[8:0]==9'd0 && DBIN_FCNT8[2:0]==3'd0)
      PTCHK_H1POS                 <= 1'b1;
   else
      PTCHK_H1POS                 <= 1'b0;
end
always @( DBIN_FCNT9 or DBIN_FCNT270 or DBIN_FCNT8 ) begin
   if ( DBIN_FCNT9[3:0]==4'd3 && DBIN_FCNT270[8:0]==9'd3 && DBIN_FCNT8[2:0]==3'd0)
      PTCHK_H2POS                 <= 1'b1;
   else
      PTCHK_H2POS                 <= 1'b0;
end

always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 ) begin
      PTCHK_CURRENT_H1[7:0]       <= 8'd0;
      PTCHK_PREVIOUS_H1[7:0]      <= 8'd0;
   end
   else if ( PTCHK_H1POS==1'b1 ) begin
      PTCHK_CURRENT_H1[7:0]       <= DBIN_DATA[63:56];
      PTCHK_PREVIOUS_H1[7:0]      <= PTCHK_CURRENT_H1[7:0];
   end
end
always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 ) begin
      PTCHK_CURRENT_H2[7:0]       <= 8'd0;
      PTCHK_PREVIOUS_H2[7:0]      <= 8'd0;
   end
   else if ( PTCHK_H2POS==1'b1 ) begin
      PTCHK_CURRENT_H2[7:0]       <= DBIN_DATA[63:56];
      PTCHK_PREVIOUS_H2[7:0]      <= PTCHK_CURRENT_H2[7:0];
   end
end


// check the H1/H2 event, include ID invert, NDF, All One, Equeal, Illegal at the end of H2
always @( DBIN_FCNT9 or DBIN_FCNT270 or DBIN_FCNT8 ) begin
   if ( DBIN_FCNT9[3:0]==4'd3 && DBIN_FCNT270[8:0]==9'd5 && DBIN_FCNT8[2:0]==3'd7)
      PTCHK_EVT_RENEW          <= 1'b1;
   else
      PTCHK_EVT_RENEW          <= 1'b0;
end

// ID invert check
wire[4:0]                 IBIT_INV_VECTOR, DBIT_INV_VECTOR;
wire[2:0]                 IBIT_INV_CNT, DBIT_INV_CNT;
assign      IBIT_INV_VECTOR[4]    = PTCHK_PREVIOUS_H1[1] ^ PTCHK_CURRENT_H1[1];
assign      IBIT_INV_VECTOR[3]    = PTCHK_PREVIOUS_H2[7] ^ PTCHK_CURRENT_H2[7];
assign      IBIT_INV_VECTOR[2]    = PTCHK_PREVIOUS_H2[5] ^ PTCHK_CURRENT_H2[5];
assign      IBIT_INV_VECTOR[1]    = PTCHK_PREVIOUS_H2[3] ^ PTCHK_CURRENT_H2[3];
assign      IBIT_INV_VECTOR[0]    = PTCHK_PREVIOUS_H2[1] ^ PTCHK_CURRENT_H2[1];

assign      DBIT_INV_VECTOR[4]    = PTCHK_PREVIOUS_H1[0] ^ PTCHK_CURRENT_H1[0];
assign      DBIT_INV_VECTOR[3]    = PTCHK_PREVIOUS_H2[6] ^ PTCHK_CURRENT_H2[6];
assign      DBIT_INV_VECTOR[2]    = PTCHK_PREVIOUS_H2[4] ^ PTCHK_CURRENT_H2[4];
assign      DBIT_INV_VECTOR[1]    = PTCHK_PREVIOUS_H2[2] ^ PTCHK_CURRENT_H2[2];
assign      DBIT_INV_VECTOR[0]    = PTCHK_PREVIOUS_H2[0] ^ PTCHK_CURRENT_H2[0];

assign      IBIT_INV_CNT[2:0]     = {2'd0, IBIT_INV_VECTOR[0]} +{2'd0, IBIT_INV_VECTOR[1]} + {2'd0, IBIT_INV_VECTOR[2]} +{2'd0, IBIT_INV_VECTOR[3]} +{2'd0, IBIT_INV_VECTOR[4]};
assign      DBIT_INV_CNT[2:0]     = {2'd0, DBIT_INV_VECTOR[0]} +{2'd0, DBIT_INV_VECTOR[1]} + {2'd0, DBIT_INV_VECTOR[2]} +{2'd0, DBIT_INV_VECTOR[3]} +{2'd0, DBIT_INV_VECTOR[4]};

always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      PTCHK_EVT_IBIT              <= 1'd0;
   else if ( PTCHK_EVT_RENEW==1'b1 )begin
      if ( IBIT_INV_CNT[2:0]==3'd5 || IBIT_INV_CNT[2:0]==3'd4 || IBIT_INV_CNT[2:0]==3'd3)
         PTCHK_EVT_IBIT           <= 1'd1;
      else
         PTCHK_EVT_IBIT           <= 1'd0;
   end
end
always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      PTCHK_EVT_DBIT              <= 1'd0;
   else if ( PTCHK_EVT_RENEW==1'b1 )begin
      if ( DBIT_INV_CNT[2:0]==3'd5 || DBIT_INV_CNT[2:0]==3'd4 || DBIT_INV_CNT[2:0]==3'd3)
         PTCHK_EVT_DBIT           <= 1'd1;
      else
         PTCHK_EVT_DBIT           <= 1'd0;
   end
end
// NDF flag check
always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      PTCHK_EVT_NDF               <= 1'd0;
   else if ( PTCHK_EVT_RENEW==1'b1 )begin
      if ( PTCHK_CURRENT_H1[7:4]==4'b1001 || PTCHK_CURRENT_H1[7:4]==4'b1000 || PTCHK_CURRENT_H1[7:4]==4'b0001 || PTCHK_CURRENT_H1[7:4]==4'b1101 || PTCHK_CURRENT_H1[7:4]==4'b1011)
          PTCHK_EVT_NDF           <= 1'd1;
      else
          PTCHK_EVT_NDF           <= 1'd0;
   end
end
// illegal point check, only chec the pointer that exceed the maximum point value
always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      PTCHK_EVT_ILLEGAL           <= 1'b0;
   else if ( PTCHK_EVT_RENEW==1'b1 )begin
      if ( {PTCHK_CURRENT_H1[1:0], PTCHK_CURRENT_H2[7:0] } )
         PTCHK_EVT_ILLEGAL        <= 1'b0;
      else
         PTCHK_EVT_ILLEGAL        <= 1'b1;
   end
end
// All One check
always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      PTCHK_EVT_AIS                <= 1'b0;
   else if ( PTCHK_EVT_RENEW==1'b1 )begin
      if ( PTCHK_CURRENT_H1[7:0]==8'hff && PTCHK_CURRENT_H2[7:0]==8'hff )
          PTCHK_EVT_AIS            <= 1'b1;
      else
          PTCHK_EVT_AIS            <= 1'b0;
   end
end
// point stable check
always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      PTCHK_EVT_STABLE             <= 1'b0;
   else if ( PTCHK_EVT_RENEW==1'b1 )begin
      if ( PTCHK_CURRENT_H1[7:0]==PTCHK_PREVIOUS_H1[7:0] && PTCHK_CURRENT_H2[7:0]==PTCHK_PREVIOUS_H2[7:0])
         PTCHK_EVT_STABLE          <= 1'b1;
      else
         PTCHK_EVT_STABLE          <= 1'b0;
   end
end
// point value capture
always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      PTCHK_EVT_PNT[9:0]           <= 10'd0;
   else if ( PTCHK_EVT_RENEW==1'b1 )
      PTCHK_EVT_PNT[9:0]           <= { PTCHK_CURRENT_H1[1:0], PTCHK_CURRENT_H2[7:0] };
end



//******                   point FSM                    ******//
wire               PTFSM_AIS_TRAN;
wire               PTFSM_LOP_TRAN;
wire               PTFSM_3PNT_NORMAL_TRAN;
wire               PTFSM_NDF_NORMAL_TRAN;

// FSM and counters renew at the cycle after event renew, FSM procedure cost 1 clock cycle, delay data and frame counters 1 clock cycle
assign  PTFSM_AIS_TRAN  = (PTFSM_CNT_AIS[1:0]==2'b10) && (PTCHK_EVT_AIS==1'b1);      // FSM change to AIS when received 3 continuously AIS event
assign  PTFSM_LOP_TRAN  = (PTFSM_CNT_NDF[3:0]==4'd8)  && (PTFSM_CNT_NDF==1'b1);      // FSM change to LOP when received 9 continuously NDF event
assign  PTFSM_3PNT_NORMAL_TRAN = PTFSM_CNT_STABLE[1:0]==2'b10 && PTCHK_EVT_STABLE==1'b1 && PTCHK_EVT_ILLEGAL==1'b0 && PTFSM_CNT_NDF==1'b0;  // FSM change to NROMAL when received 9 continuously stable legal point
assign  PTFSM_NDF_NORMAL_TRAN  = PTFSM_CNT_NDF[3:0]!=4'd8 && PTFSM_CNT_NDF==1'b1 && PTCHK_EVT_ILLEGAL==1'b0;                                // FSM change to NROMAL when received a legal point with NDF and not with LOP condition

always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      PTFSM_RENEW                  <= 1'b0;
   else
      PTFSM_RENEW                  <= PTCHK_EVT_RENEW;
end
always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      PTFSM_FSM                    <= C_FSM_LOP;
   else if ( PTFSM_RENEW==1'b1 ) begin
      case ( PTFSM_FSM )
      C_FSM_LOP : begin
         if ( PTFSM_AIS_TRAN==1'b1 || DBIN_FAS_FAIL==1'b1 || DBIN_SOH_FAIL==1'b1 )
            PTFSM_FSM              <= C_FSM_AIS;
         else if ( PTFSM_3PNT_NORMAL_TRAN==1'b1 )
            PTFSM_FSM              <= C_FSM_NORMAL;
         else if ( PTFSM_NDF_NORMAL_TRAN==1'b1 )
            PTFSM_FSM              <= C_FSM_NORMAL;
         else
            PTFSM_FSM              <= C_FSM_LOP;
      end
      C_FSM_AIS : begin
         if ( PTFSM_3PNT_NORMAL_TRAN==1'b1 )
            PTFSM_FSM              <= C_FSM_NORMAL;
         else if ( PTFSM_NDF_NORMAL_TRAN==1'b1 )
            PTFSM_FSM              <= C_FSM_NORMAL;
         else if ( PTFSM_LOP_TRAN==1'b1 )
            PTFSM_FSM              <= C_FSM_LOP;
         else
            PTFSM_FSM              <= C_FSM_AIS;
      end
      C_FSM_NORMAL : begin
         if ( PTFSM_AIS_TRAN==1'b1 || DBIN_FAS_FAIL==1'b1 || DBIN_SOH_FAIL==1'b1 )
            PTFSM_FSM              <= C_FSM_AIS;
         else if ( PTFSM_LOP_TRAN==1'b1 ) begin
            PTFSM_FSM              <= C_FSM_LOP;
         end
         else if ( PTCHK_EVT_IBIT==1'b1 && PTCHK_EVT_DBIT==1'b0 )
            PTFSM_FSM              <= C_FSM_INC;
         else if ( PTCHK_EVT_IBIT==1'b0 && PTCHK_EVT_DBIT==1'b1 )
            PTFSM_FSM              <= C_FSM_DEC;
         else
            PTFSM_FSM              <= C_FSM_NORMAL;
      end
      C_FSM_INC : begin
            PTFSM_FSM              <= C_FSM_NORMAL;
      end
      C_FSM_DEC : begin
            PTFSM_FSM              <= C_FSM_NORMAL;
      end
      default   : begin
         PTFSM_FSM                 <= C_FSM_LOP;
      end
      endcase
   end
end

// AIS count, count received continuously AIS, clear when received no-AIS point
always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      PTFSM_CNT_AIS[1:0]                 <= 2'd0;
   else if ( PTFSM_RENEW==1'b1 ) begin
      if ( PTCHK_EVT_AIS==1'b0 )
         PTFSM_CNT_AIS[1:0]              <= 2'd0;
      else if ( PTCHK_EVT_AIS==1'b1 && PTFSM_CNT_AIS[1:0]!=2'd2 )
         PTFSM_CNT_AIS[1:0]              <= PTFSM_CNT_AIS[1:0] +2'd1;
   end
end
// NDF count, count received continuously NDF, clear when received no-NDF point
always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      PTFSM_CNT_NDF[3:0]                 <= 4'd0;
   else if ( PTFSM_RENEW==1'b1 ) begin
      if ( PTCHK_EVT_NDF==1'b0 )
         PTFSM_CNT_NDF[3:0]              <= 4'd0;
      else if ( PTCHK_EVT_NDF==1'b1 && PTFSM_CNT_NDF[3:0]!=4'd8 )
         PTFSM_CNT_NDF[3:0]              <= PTFSM_CNT_NDF[3:0] +4'd1;
   end
end
// stable point count
always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      PTFSM_CNT_STABLE[1:0]              <= 2'd0;
   else if ( PTFSM_RENEW==1'b1 ) begin
      if ( PTCHK_EVT_STABLE==1'b1 && PTCHK_EVT_ILLEGAL==1'b0 && PTCHK_EVT_NDF==1'b0 ) begin
         if ( PTFSM_CNT_STABLE[1:0]!=2'd2 )
            PTFSM_CNT_STABLE[1:0]        <= PTFSM_CNT_STABLE[1:0] +2'd1;
         else
            PTFSM_CNT_STABLE[1:0]        <= PTFSM_CNT_STABLE[1:0];
      end
   end
end
// unstable point count
always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      PTFSM_CNT_UNSTABLE[3:0]            <= 4'd0;
   else if ( PTFSM_RENEW==1'b1 ) begin
      if ( PTCHK_EVT_STABLE==1'b0 )
         PTFSM_CNT_UNSTABLE[3:0]         <= 4'd0;
      else if ( PTCHK_EVT_STABLE==1'b1 && PTFSM_CNT_UNSTABLE[3:0]!=4'd8 )
         PTFSM_CNT_UNSTABLE[3:0]         <= PTFSM_CNT_UNSTABLE[3:0] +4'd1;
   end
end
// PTR value extract, capture when normal status and 
always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      PTFSM_PNT[9:0]                     <= 10'd0;
   else if ( PTFSM_RENEW==1'b1 ) begin
      if ( PTFSM_NDF_NORMAL_TRAN==1'b1 ) 
         PTFSM_PNT[9:0]                  <= PTCHK_EVT_PNT[9:0];
      else if ( PTFSM_3PNT_NORMAL_TRAN==1'b1 )
         PTFSM_PNT[9:0]                  <= PTCHK_EVT_PNT[9:0];
      else if ( PTFSM_FSM==C_FSM_INC ) begin
         if ( PTFSM_PNT[9:0]==10'd782 )
            PTFSM_PNT[9:0]               <= 10'd0;
         else
            PTFSM_PNT[9:0]               <= PTFSM_PNT[9:0] +10'd1;
      end
      else if ( PTFSM_FSM==C_FSM_DEC ) begin
         if ( PTFSM_PNT[9:0]==10'd0 )
            PTFSM_PNT[9:0]               <= 10'd782;
         else
            PTFSM_PNT[9:0]               <= PTFSM_PNT[9:0] -10'd1;
      end
   end
end
// delay data and frame count wait for point FSM tran
always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 ) begin
      PTFSM_FCNT8[2:0]                   <= 3'd0;
      PTFSM_FCNT270[8:0]                 <= 9'd0;
      PTFSM_FCNT9[3:0]                   <= 4'd0;
      PTFSM_DATA[63:0]                   <= 64'd0;
   end
   else begin
      PTFSM_FCNT8[2:0]                   <= DBIN_FCNT8[2:0];
      PTFSM_FCNT270[8:0]                 <= DBIN_FCNT270[8:0];
      PTFSM_FCNT9[3:0]                   <= DBIN_FCNT9[3:0];
      PTFSM_DATA[63:0]                   <= DBIN_DATA[63:0];
   end
end



//******                   SPE/J1 generate                    ******//
assign      J1SPE_BASE_EN        = ( PTFSM_FCNT270>=9'd9 );
always @( PTFSM_FCNT270 or PTFSM_FCNT9 or PTFSM_FSM or J1SPE_BASE_EN ) begin
   if ( PTFSM_FSM==C_FSM_INC ) begin
      if ( PTFSM_FCNT9[3:0]==4'd3 && ( PTFSM_FCNT270[8:0]==9'd9 || PTFSM_FCNT270[8:0]==9'd10 || PTFSM_FCNT270[8:0]==9'd11) )
         J1SPE_DATAEN           <= 1'b0;
      else
         J1SPE_DATAEN           <= J1SPE_BASE_EN;
   end
   else if ( PTFSM_FSM==C_FSM_DEC ) begin
      if ( PTFSM_FCNT9[3:0]==4'd3 && ( PTFSM_FCNT270[8:0]==9'd6 || PTFSM_FCNT270[8:0]==9'd7 || PTFSM_FCNT270[8:0]==9'd8) )
         J1SPE_DATAEN           <= 1'b1;
      else
         J1SPE_DATAEN           <= J1SPE_BASE_EN;
   end
   else if ( PTFSM_FSM==C_FSM_NORMAL )begin
         J1SPE_DATAEN           <= J1SPE_BASE_EN;
   end
   else begin
         J1SPE_DATAEN           <= 1'b0;
   end
end

always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      J1SPE_J1CNT[1:0]          <= 2'd0;
   else if ( PTFSM_FCNT8[2:0]==3'd7 && J1SPE_DATAEN==1'b1 ) begin
      if ( J1SPE_J1CNT[1:0]==2'd2 )
         J1SPE_J1CNT[1:0]       <= 2'd0;
      else
         J1SPE_J1CNT[1:0]       <= J1SPE_J1CNT[1:0] +2'd1;
   end
end
always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      J1SPE_J1CNT[11:2]                  <= 10'd0;
   else if ( PTFSM_FCNT8[2:0]==3'd7 ) begin
      if ( PTFSM_FSM==C_FSM_NORMAL && ( PTFSM_FCNT9[3:0]==4'd3 && PTFSM_FCNT270[8:0]==9'd8 ) ) begin  // reload J1CNT at normal status H3
         if ( PTFSM_PNT[9:0]==10'd0 )
            J1SPE_J1CNT[11:2]            <= 10'd0;
         else
            J1SPE_J1CNT[11:2]            <= 10'd783- PTFSM_PNT[9:0];
      end
      else if ( J1SPE_DATAEN==1'b1 && J1SPE_J1CNT[1:0]==2'd2 && PTFSM_FCNT8[2:0]==3'd7 ) begin
         if ( J1SPE_J1CNT[11:2]==10'd782 )
            J1SPE_J1CNT[11:2]            <= 10'd0;
         else
            J1SPE_J1CNT[11:2]            <= J1SPE_J1CNT[11:2] +10'd1;
      end
   end
end

always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 ) begin
      DBOUT_FCNT8[2:0]              <= 3'd0;
      DBOUT_FCNT270[8:0]            <= 9'd0;
      DBOUT_FCNT9[3:0]              <= 4'd0;
      DBOUT_DATA[63:0]              <= 64'd0;
      DBOUT_SPE                     <= 1'b0;
   end
   else begin
      DBOUT_FCNT8[2:0]              <= PTFSM_FCNT8[2:0];
      DBOUT_FCNT270[8:0]            <= PTFSM_FCNT270[8:0];
      DBOUT_FCNT9[3:0]              <= PTFSM_FCNT9[3:0];
      DBOUT_DATA[63:0]              <= PTFSM_DATA[63:0];
      DBOUT_SPE                     <= J1SPE_DATAEN;
   end
end
always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      DBOUT_J1                      <= 1'b0;
   else begin
      if ( J1SPE_J1CNT[11:0]==11'd0 && J1SPE_DATAEN==1'b1 )
         DBOUT_J1                   <= 1'b1;
      else
         DBOUT_J1                   <= 1'b0;
   end
end

endmodule
